home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / wwbbs31_source.lha / WWBBS / WWBBSSrc / wwbbs.c < prev    next >
C/C++ Source or Header  |  1995-06-26  |  33KB  |  1,041 lines

  1. #include <exec/types.h>
  2. #include <exec/exec.h>
  3. #include <dos/dos.h>
  4. #include <dos/dostags.h>
  5. #include <intuition/intuition.h>
  6. #include <libraries/asl.h>
  7. #include <libraries/commodities.h>
  8. #include <libraries/gadtools.h>
  9. #include <libraries/triton.h>
  10. #include <libraries/wwbbs.h>
  11. #include <devices/console.h>
  12. #include <devices/conunit.h>
  13. #include <devices/serial.h>
  14. #include <devices/timer.h>
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <time.h>
  20.  
  21. #include <proto/asl.h>
  22. #include <proto/commodities.h>
  23. #include <proto/diskfont.h>
  24. #include <proto/dos.h>
  25. #include <proto/exec.h>
  26. #include <proto/gadtools.h>
  27. #include <proto/graphics.h>
  28. #include <proto/icon.h>
  29. #include <proto/intuition.h>
  30. #include <proto/triton.h>
  31. #include <proto/utility.h>
  32. #include <proto/wwbbs.h>
  33.  
  34. #include "Data:Programs/Include/wwbbs_update.h"
  35.  
  36. #include "wwbbs.h"
  37.  
  38. #include "wwbbs_settings.h"
  39.  
  40. #include "wwbbs_rev.h"
  41.  
  42. char *version=VERSTAG;
  43.  
  44. long __stack=10000;
  45.  
  46. struct Library *WorldWideBase;
  47.  
  48. struct MonitorNode {
  49.     struct Node mn_Node;
  50.     BYTE mn_Text[128];
  51.     BYTE mn_Name[33];
  52. };
  53.  
  54. struct ActionNode {
  55.     struct Node an_Node;
  56.     BYTE an_Name[33];
  57.     BYTE an_Command[256];
  58. };
  59.  
  60. struct List *CreateList(void);
  61. void DeleteList(struct List *);
  62. struct Node *GetNode(struct List *,ULONG);
  63. ULONG GetNodeNum(struct List *,BYTE *);
  64. void UpdateStatus(struct TR_Project *,struct MonitorNode *);
  65. void close_all(void);
  66.  
  67. #define StatusText(text,id,minwidth) HorizGroupSA,TextID(text,id),TRAT_MinWidth,minwidth,Space,EndGroup
  68.  
  69. BYTE sessions_buff[128];
  70. BYTE access_buff[128];
  71. BYTE ratio_buff[128];
  72. BYTE time_buff[128];
  73. BYTE email_buff[128];
  74. BYTE messages_buff[128];
  75. BYTE files_buff[128];
  76. BYTE credits_buff[128];
  77.  
  78. struct SignalSemaphore settings_semaphore;
  79. struct SettingsStruct settings;
  80.  
  81. ProjectDefinition(wwbbs_trwintags)
  82.     {
  83.         WindowID(1),WindowPosition(TRWP_CENTERDISPLAY),
  84.         WindowTitle("World Wide BBS"),
  85.  
  86.         BeginMenu("Project"),
  87.             MenuItem("?_About...",101),
  88.             ItemBarlabel,
  89.             MenuItem("H_Hide",102),
  90.             MenuItem("Q_Quit",103),
  91.         BeginMenu("Settings"),
  92.             MenuItem("M_Screen Mode...",201),
  93.             MenuItem("F_Font...",202),
  94.             ItemBarlabel,
  95.             MenuItem("S_Save settings",203),
  96.  
  97.         VertGroupA,
  98.             Space,
  99.             HorizGroupA,
  100.                 Space,
  101.                 ListSS(NULL,1,0,0),TRAT_MinWidth,40,
  102.                 Space,
  103.                 ListSel(NULL,2,0),TRAT_MinWidth,20,
  104.                 Space,
  105.             EndGroup,
  106.             Space,
  107.             HorizGroup,
  108.                 Space,
  109.                 _TextBox,
  110.                 HorizGroup,
  111.                     Space,
  112.                     VertGroupEA,
  113.                         SpaceS,
  114.                         TextN("Sessions:"),
  115.                         TextN("Access:"),
  116.                         TextN("Ratio:"),
  117.                         TextN("Time:"),
  118.                         TextN("Email:"),
  119.                         TextN("Messages:"),
  120.                         TextN("Files:"),
  121.                         TextN("Credits:"),
  122.                         SpaceS,
  123.                     EndGroup,
  124.                     SpaceS,
  125.                     VertGroupEA,
  126.                         SpaceS,
  127.                         StatusText(NULL,3,10),
  128.                         StatusText(NULL,4,3),
  129.                         StatusText(NULL,5,30),
  130.                         StatusText(NULL,6,25),
  131.                         StatusText(NULL,7,40),
  132.                         StatusText(NULL,8,40),
  133.                         StatusText(NULL,9,60),
  134.                         StatusText(NULL,10,40),
  135.                         SpaceS,
  136.                     EndGroup,
  137.                     Space,
  138.                 EndGroup,
  139.                 Space,
  140.             EndGroup,
  141.             Space,
  142.         EndGroup,
  143.  
  144.         EndProject
  145.     };
  146.  
  147. void main(int argc,char **argv)
  148.     {
  149.         if(TR_OpenTriton(TRITON10VERSION,TRCA_Name,"WWBBS",TRCA_LongName,"World Wide BBS",TRCA_Info,"Bulletin Board System",TRCA_Version,"2",TRCA_Release,"1",TRCA_Date,DATE,TAG_END))
  150.             {
  151.  
  152.         if(!(WorldWideBase=OpenLibrary("wwbbs.library",0)))
  153.             close_all();
  154.  
  155.         {
  156.             BPTR fh;
  157.             if(fh=Open("WWBBS:WWBBS.settings",MODE_OLDFILE))
  158.                 {
  159.                     FRead(fh,&settings,sizeof(struct SettingsStruct),1);
  160.                     Close(fh);
  161.                 }
  162.             else
  163.                 {
  164.                     settings.display_id=INVALID_ID;
  165.                     settings.display_depth=3;
  166.                     strcpy(settings.font_name,"");
  167.                     settings.font_ysize=0;
  168.                 }
  169.             InitSemaphore(&settings_semaphore);
  170.         }
  171.         {
  172.             struct MsgPort *BrokerMP;
  173.             CxObj *Broker,*Filter,*Sender,*Translate;
  174.             char **tooltypes;
  175.             tooltypes=ArgArrayInit(argc,argv);
  176.             if(BrokerMP=CreateMsgPort())
  177.                 {
  178.                     struct NewBroker nb={ NB_VERSION,"World Wide BBS",NULL,"Bulletin Board System",NBU_UNIQUE|NBU_NOTIFY,COF_SHOW_HIDE,0,0,0 };
  179.                     nb.nb_Title=&version[6];
  180.                     nb.nb_Port=BrokerMP;
  181.                     nb.nb_Pri=(BYTE) ArgInt(tooltypes,"CX_PRIORITY",0);
  182.                     if(Broker=CxBroker(&nb,NULL))
  183.                         {
  184.                             if(Filter=CxFilter(ArgString(tooltypes,"CX_POPKEY","control alt w")))
  185.                                 {
  186.                                     AttachCxObj(Broker,Filter);
  187.                                     if(Sender=CxSender(BrokerMP,1))
  188.                                         {
  189.                                             AttachCxObj(Filter,Sender);
  190.                                             if(Translate=CxTranslate(NULL))
  191.                                                 {
  192.                                                     AttachCxObj(Filter,Translate);
  193.                                                     if(!CxObjError(Filter))
  194.                                                         {
  195.                                                             ActivateCxObj(Broker,TRUE);
  196.  
  197.     /* Set up update port... */
  198.     {
  199.         struct MsgPort *update_port;
  200.         if(update_port=CreateMsgPort())
  201.             {
  202.                 SetUpdatePort(update_port);
  203.  
  204.     /* Start up nodes... */
  205.     {
  206.         ULONG next=NULL;
  207.         BYTE *name;
  208.         UBYTE type=NULL;
  209.         BOOL frontend=FALSE;
  210.         while(next=GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,&name,CFGTAG_Next,next,NDTAG_Type,&type,NDTAG_FrontEnd,&frontend,TAG_END))
  211.             {
  212.                 switch(type)
  213.                     {
  214.                         case NDTYP_Local:
  215.                             break;
  216.                         case NDTYP_Remote:
  217.                             if(!frontend)
  218.                                 StartProcess("WWBBS Node",NodeProc,20000,name);
  219.                             else
  220.                                 StartProcess("WWBBS Node",NodeFrontEndProc,20000,name);
  221.                             break;
  222.                     }
  223.             }
  224.     }
  225.  
  226.     /* Main */
  227.     {
  228.         struct List *node_list=NULL;
  229.         {
  230.             struct List action_list;
  231.             ULONG selected=0;
  232.             BOOL kg=TRUE;
  233.             struct TR_Project *project=NULL;
  234.             NewList(&action_list);
  235.             {
  236.                 UBYTE **p;
  237.                 for(p=tooltypes;*p;p++)
  238.                     {
  239.                         if(!strnicmp(*p,"ACTION",6))
  240.                             {
  241.                                 char *q,*r;
  242.                                 if(q=strchr(*p,'='))
  243.                                     {
  244.                                         char name[33],command[256];
  245.                                         strcpy(name,"");
  246.                                         strcpy(command,"");
  247.                                         q++;
  248.                                         if(r=strchr(q,','))
  249.                                             {
  250.                                                 r++;
  251.                                                 sprintf(name,"%.*s",r-q-1,q);
  252.                                                 sprintf(command,"%.255s",r);
  253.                                                 {
  254.                                                     struct ActionNode *node;
  255.                                                     if(node=AllocVec(sizeof(struct ActionNode),MEMF_CLEAR))
  256.                                                         {
  257.                                                             strcpy(node->an_Name,name);
  258.                                                             strcpy(node->an_Command,command);
  259.                                                             node->an_Node.ln_Name=node->an_Name;
  260.                                                             AddTail(&action_list,(struct Node *) node);
  261.                                                         }
  262.                                                 }
  263.                                             }
  264.                                     }
  265.                             }
  266.                     }
  267.             }
  268.             if(!stricmp(ArgString(tooltypes,"CX_POPUP","YES"),"YES"))
  269.                 {
  270.                     if(project=TR_OpenProject(Application,wwbbs_trwintags))
  271.                         {
  272.                             if(node_list=CreateList())
  273.                                 {
  274.                                     TR_SetAttribute(project,1,0,(ULONG) node_list);
  275.                                     selected=0;
  276.                                     TR_SetAttribute(project,1,TRAT_Value,selected);
  277.                                     {
  278.                                         struct MonitorNode *node;
  279.                                         if(node=(struct MonitorNode *) GetNode(node_list,selected))
  280.                                             UpdateStatus(project,node);
  281.                                     }
  282.                                 }
  283.                             TR_SetAttribute(project,2,0,(ULONG) &action_list);
  284.                         }
  285.                     else
  286.                         TR_EasyRequestTags(Application,TR_GetErrorString(TR_GetLastError(Application)),"Okay",TREZ_ReqPos,TRWP_CENTERDISPLAY,TREZ_Title,"World Wide BBS Error Request",TAG_END);
  287.                 }
  288.             while(kg)
  289.                 {
  290.                     if(project)
  291.                         {
  292.                             ULONG mask;
  293.                             mask=TR_Wait(Application,(1 << BrokerMP->mp_SigBit) | (1 << update_port->mp_SigBit));
  294.                             if(mask & (1 << BrokerMP->mp_SigBit))
  295.                                 {
  296.                                     CxMsg *msg;
  297.                                     ULONG id,type;
  298.                                     while(kg && project && (msg=(CxMsg *) GetMsg(BrokerMP)))
  299.                                         {
  300.                                             id=CxMsgID(msg);
  301.                                             type=CxMsgType(msg);
  302.                                             ReplyMsg((struct Message *) msg);
  303.                                             switch(type)
  304.                                                 {
  305.                                                     case CXM_IEVENT:
  306.                                                         switch(id)
  307.                                                             {
  308.                                                                 case 1:
  309.                                                                     WindowToFront(project->trp_Window);
  310.                                                                     ActivateWindow(project->trp_Window);
  311.                                                                     break;
  312.                                                             }
  313.                                                         break;
  314.                                                     case CXM_COMMAND:
  315.                                                         switch(id)
  316.                                                             {
  317.                                                                 case CXCMD_DISABLE:
  318.                                                                     ActivateCxObj(Broker,FALSE);
  319.                                                                     break;
  320.                                                                 case CXCMD_ENABLE:
  321.                                                                     ActivateCxObj(Broker,TRUE);
  322.                                                                     break;
  323.                                                                 case CXCMD_APPEAR:
  324.                                                                     WindowToFront(project->trp_Window);
  325.                                                                     ActivateWindow(project->trp_Window);
  326.                                                                     break;
  327.                                                                 case CXCMD_DISAPPEAR:
  328.                                                                     TR_CloseProject(project);
  329.                                                                     project=NULL;
  330.                                                                     break;
  331.                                                                 case CXCMD_KILL:
  332.                                                                     TR_CloseProject(project);
  333.                                                                     project=NULL;
  334.                                                                     kg=FALSE;
  335.                                                                     break;
  336.                                                                 case CXCMD_UNIQUE:
  337.                                                                     WindowToFront(project->trp_Window);
  338.                                                                     ActivateWindow(project->trp_Window);
  339.                                                                     break;
  340.                                                             }
  341.                                                         break;
  342.                                                 }
  343.                                         }
  344.                                 }
  345.                             if(mask & (1 << update_port->mp_SigBit))
  346.                                 {
  347.                                     struct UpdateMessage *msg;
  348.                                     while(msg=(struct UpdateMessage *) GetMsg(update_port))
  349.                                         {
  350.                                             switch(msg->um_Command)
  351.                                                 {
  352.                                                     case UPDCMD_UpdateStatus:
  353.                                                         {
  354.                                                             BYTE selected_name[33];
  355.                                                             strcpy(selected_name,"");
  356.                                                             {
  357.                                                                 struct MonitorNode *node;
  358.                                                                 if(node=(struct MonitorNode *) GetNode(node_list,selected))
  359.                                                                     strcpy(selected_name,node->mn_Name);
  360.                                                             }
  361.                                                             TR_SetAttribute(project,1,0,NULL);
  362.                                                             if(node_list) DeleteList(node_list);
  363.                                                             selected=0;
  364.                                                             if(node_list=CreateList())
  365.                                                                 {
  366.                                                                     TR_SetAttribute(project,1,0,(ULONG) node_list);
  367.                                                                     selected=GetNodeNum(node_list,selected_name);
  368.                                                                 }
  369.                                                             TR_SetAttribute(project,1,TRAT_Value,selected);
  370.                                                             {
  371.                                                                 struct MonitorNode *node;
  372.                                                                 node=(struct MonitorNode *) GetNode(node_list,selected);
  373.                                                                 UpdateStatus(project,node);
  374.                                                             }
  375.                                                         }
  376.                                                         break;
  377.                                                     case UPDCMD_StartupNode:
  378.                                                         {
  379.                                                             UBYTE type=0;
  380.                                                             BOOL frontend=FALSE;
  381.                                                             if(GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,msg->um_ID,NDTAG_Type,&type,NDTAG_FrontEnd,&frontend,TAG_END))
  382.                                                                 {
  383.                                                                     switch(type)
  384.                                                                         {
  385.                                                                             case NDTYP_Local:
  386.                                                                                 break;
  387.                                                                             case NDTYP_Remote:
  388.                                                                                 if(!frontend)
  389.                                                                                     StartProcess("WWBBS Node",NodeProc,20000,(BYTE *) msg->um_ID);
  390.                                                                                 else
  391.                                                                                     StartProcess("WWBBS Node",NodeFrontEndProc,20000,(BYTE *) msg->um_ID);
  392.                                                                                 break;
  393.                                                                         }
  394.                                                                 }
  395.                                                         }
  396.                                                         break;
  397.                                                     case UPDCMD_KillNode:
  398.                                                         {
  399.                                                             char task[64];
  400.                                                             BOOL istask=TRUE;
  401.                                                             sprintf(task,"WWBBS Local.%s",(BYTE *) msg->um_ID);
  402.                                                             while(istask)
  403.                                                                 {
  404.                                                                     Forbid();
  405.                                                                     istask=(FindTask(task)) ? TRUE : FALSE;
  406.                                                                     Permit();
  407.                                                                     if(istask)
  408.                                                                         {
  409.                                                                             while(!NodeCommandTags((BYTE *) msg->um_ID,NDCMD_Panic,TAG_END))
  410.                                                                                 Delay(25L);
  411.                                                                         }
  412.                                                                 }
  413.                                                         }
  414.                                                         KillProcess("WWBBS Node",(BYTE *) msg->um_ID);
  415.                                                         break;
  416.                                                 }
  417.                                             FreeVec(msg);
  418.                                         }
  419.                                 }
  420.  
  421.                             {
  422.                                 struct TR_Message *msg;
  423.                                 while(kg && project && (msg=TR_GetMsg(Application)))
  424.                                     {
  425.                                         if(msg->trm_Project==project)
  426.                                             {
  427.                                                 switch(msg->trm_Class)
  428.                                                     {
  429.                                                         case TRMS_CLOSEWINDOW:
  430.                                                             TR_CloseProject(project);
  431.                                                             project=NULL;
  432.                                                             break;
  433.                                                         case TRMS_NEWVALUE:
  434.                                                             switch(msg->trm_ID)
  435.                                                                 {
  436.                                                                     case 1: /* Node List */
  437.                                                                         selected=msg->trm_Data;
  438.                                                                         {
  439.                                                                             struct MonitorNode *node;
  440.                                                                             if(node=(struct MonitorNode *) GetNode(node_list,selected))
  441.                                                                                 UpdateStatus(project,node);
  442.                                                                         }
  443.                                                                         if(msg->trm_Qualifier & IEQUALIFIER_REPEAT)
  444.                                                                             {
  445.                                                                                 struct MonitorNode *node;
  446.                                                                                 if(node=(struct MonitorNode *) GetNode(node_list,selected))
  447.                                                                                     {
  448.                                                                                         UBYTE type=0;
  449.                                                                                         GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,node->mn_Name,NDTAG_Type,&type,TAG_END);
  450.                                                                                         switch(type)
  451.                                                                                             {
  452.                                                                                                 case NDTYP_Local:
  453.                                                                                                     {
  454.                                                                                                         char task[64];
  455.                                                                                                         BOOL istask=FALSE;
  456.                                                                                                         sprintf(task,"WWBBS Local.%s",node->mn_Name);
  457.                                                                                                         Forbid();
  458.                                                                                                         istask=(FindTask(task)) ? TRUE : FALSE;
  459.                                                                                                         Permit();
  460.                                                                                                         if(istask)
  461.                                                                                                             ConsoleCommandTags(node->mn_Name,CONCMD_Open,TAG_END);
  462.                                                                                                         else
  463.                                                                                                             StartProcess("WWBBS Local",LocalLogonProc,20000,node->mn_Name);
  464.                                                                                                     }
  465.                                                                                                     break;
  466.                                                                                                 case NDTYP_Remote:
  467.                                                                                                     ConsoleCommandTags(node->mn_Name,CONCMD_Open,TAG_END);
  468.                                                                                                     break;
  469.                                                                                             }
  470.                                                                                     }
  471.                                                                             }
  472.                                                                         break;
  473.                                                                     case 2: /* Action List */
  474.                                                                         {
  475.                                                                             struct ActionNode *node;
  476.                                                                             if(node=(struct ActionNode *) GetNode(&action_list,msg->trm_Data))
  477.                                                                                 {
  478.                                                                                     {
  479.                                                                                         BOOL specify_node=FALSE;
  480.                                                                                         {
  481.                                                                                             char *p;
  482.                                                                                             if(p=strchr(node->an_Command,'%'))
  483.                                                                                                 {
  484.                                                                                                     p++;
  485.                                                                                                     if(*p=='s')
  486.                                                                                                         specify_node=TRUE;
  487.                                                                                                 }
  488.                                                                                         }
  489.                                                                                         if(specify_node)
  490.                                                                                             {
  491.                                                                                                 if(GetNode(node_list,selected))
  492.                                                                                                     {
  493.                                                                                                         char buff[256+32-2],*p=NULL;
  494.                                                                                                         {
  495.                                                                                                             struct MonitorNode *node;
  496.                                                                                                             if(node=(struct MonitorNode *) GetNode(node_list,selected))
  497.                                                                                                                 p=node->mn_Name;
  498.                                                                                                         }
  499.                                                                                                         if(p)
  500.                                                                                                             {
  501.                                                                                                                 sprintf(buff,node->an_Command,p);
  502.                                                                                                                 SystemTags(buff,TAG_END);
  503.                                                                                                             }
  504.                                                                                                     }
  505.                                                                                                 else
  506.                                                                                                     TR_EasyRequestTags(Application,"Please select a node first.","Okay",TREZ_LockProject,project,TREZ_Title,"World Wide BBS",TAG_END);
  507.                                                                                             }
  508.                                                                                         else
  509.                                                                                             SystemTags(node->an_Command,TAG_END);
  510.                                                                                     }
  511.                                                                                 }
  512.                                                                         }
  513.                                                                         break;
  514.                                                                 }
  515.                                                             break;
  516.                                                         case TRMS_ACTION:
  517.                                                             switch(msg->trm_ID)
  518.                                                                 {
  519.                                                                     case 101: /* About... */
  520.                                                                         {
  521.                                                                             char s[256];
  522.                                                                             sprintf(s,"%%3World Wide BBS 2.5 (%s)\n%%nCopyright ⌐ 1995 Arthur Choung\tInternet: choung@seas.ucla.edu or arthur@qedbbs.com\nUS Mail: 10324 Chestnut Street, Bellflower, CA 90706 USA",DATE);
  523.                                                                             TR_EasyRequestTags(Application,s,"Okay",TREZ_ReqPos,TRWP_CENTERDISPLAY,TREZ_LockProject,project,TREZ_Title,"About World Wide BBS...",TAG_END);
  524.                                                                         }
  525.                                                                         break;
  526.                                                                     case 102: /* Hide */
  527.                                                                         TR_CloseProject(project);
  528.                                                                         project=NULL;
  529.                                                                         break;
  530.                                                                     case 103: /* Quit */
  531.                                                                         TR_CloseProject(project);
  532.                                                                         project=NULL;
  533.                                                                         kg=FALSE;
  534.                                                                         break;
  535.                                                                     case 201: /* Display Mode... */
  536.                                                                         ObtainSemaphore(&settings_semaphore);
  537.                                                                         TR_LockProject(project);
  538.                                                                         {
  539.                                                                             if(AslBase->lib_Version>=38)
  540.                                                                                 {
  541.                                                                                     struct ScreenModeRequester *req;
  542.                                                                                     if(req=AllocAslRequestTags(ASL_ScreenModeRequest,
  543.                                                                                             ASLSM_Window,project->trp_Window,
  544.                                                                                             ASLSM_TitleText,"Select Screen Mode...",
  545.                                                                                             ASLSM_InitialDisplayID,settings.display_id,
  546.                                                                                             ASLSM_InitialDisplayDepth,settings.display_depth,
  547.                                                                                             ASLSM_DoDepth,TRUE,
  548.                                                                                             ASLSM_MinDepth,3,
  549.                                                                                             ASLSM_MaxDepth,4,
  550.                                                                                             TAG_END))
  551.                                                                                         {
  552.                                                                                             if(AslRequestTags(req,TAG_END))
  553.                                                                                                 {
  554.                                                                                                     settings.display_id=req->sm_DisplayID;
  555.                                                                                                     settings.display_depth=req->sm_DisplayDepth;
  556.                                                                                                 }
  557.                                                                                             FreeAslRequest(req);
  558.                                                                                         }
  559.                                                                                 }
  560.                                                                             else
  561.                                                                                 TR_EasyRequestTags(Application,"You need asl.library V38","Okay",TREZ_ReqPos,TRWP_CENTERDISPLAY,TREZ_Title,"World Wide BBS Error Request",TAG_END);
  562.                                                                         }
  563.                                                                         TR_UnlockProject(project);
  564.                                                                         ReleaseSemaphore(&settings_semaphore);
  565.                                                                         break;
  566.                                                                     case 202: /* Font... */
  567.                                                                         ObtainSemaphore(&settings_semaphore);
  568.                                                                         TR_LockProject(project);
  569.                                                                         {
  570.                                                                             struct FontRequester *req;
  571.                                                                             if(req=AllocAslRequestTags(ASL_FontRequest,
  572.                                                                                     ASLFO_Window,project->trp_Window,
  573.                                                                                     ASLFO_TitleText,"Select Font...",
  574.                                                                                     ASLFO_InitialName,settings.font_name,
  575.                                                                                     ASLFO_InitialSize,settings.font_ysize,
  576.                                                                                     TAG_END))
  577.                                                                                 {
  578.                                                                                     if(AslRequestTags(req,TAG_END))
  579.                                                                                         {
  580.                                                                                             if(strlen(req->fo_Attr.ta_Name)<256)
  581.                                                                                                 strcpy(settings.font_name,req->fo_Attr.ta_Name);
  582.                                                                                             else
  583.                                                                                                 {
  584.                                                                                                     strncpy(settings.font_name,req->fo_Attr.ta_Name,255);
  585.                                                                                                     settings.font_name[255]=NULL;
  586.                                                                                                 }
  587.                                                                                             settings.font_ysize=req->fo_Attr.ta_YSize;
  588.                                                                                         }
  589.                                                                                     FreeAslRequest(req);
  590.                                                                                 }
  591.                                                                         }
  592.                                                                         TR_UnlockProject(project);
  593.                                                                         ReleaseSemaphore(&settings_semaphore);
  594.                                                                         break;
  595.                                                                     case 203: /* Save */
  596.                                                                         ObtainSemaphore(&settings_semaphore);
  597.                                                                         {
  598.                                                                             BPTR fh;
  599.                                                                             if(fh=Open("WWBBS:WWBBS.settings",MODE_NEWFILE))
  600.                                                                                 {
  601.                                                                                     FWrite(fh,&settings,sizeof(struct SettingsStruct),1);
  602.                                                                                     Close(fh);
  603.                                                                                 }
  604.                                                                         }
  605.                                                                         ReleaseSemaphore(&settings_semaphore);
  606.                                                                         break;
  607.                                                                 }
  608.                                                             break;
  609.                                                     }
  610.                                             }
  611.                                         TR_ReplyMsg(msg);
  612.                                     }
  613.                             }
  614.                         }
  615.                     else
  616.                         {
  617.                             ULONG mask;
  618.                             CxMsg *msg;
  619.                             ULONG id,type;
  620.                             mask=Wait((1 << BrokerMP->mp_SigBit) | (1 << update_port->mp_SigBit));
  621.                             if(mask & (1 << BrokerMP->mp_SigBit))
  622.                                 {
  623.                                     while(kg && !project && (msg=(CxMsg *) GetMsg(BrokerMP)))
  624.                                         {
  625.                                             id=CxMsgID(msg);
  626.                                             type=CxMsgType(msg);
  627.                                             ReplyMsg((struct Message *) msg);
  628.                                             switch(type)
  629.                                                 {
  630.                                                     case CXM_IEVENT:
  631.                                                         switch(id)
  632.                                                             {
  633.                                                                 case 1:
  634.                                                                     if(project=TR_OpenProject(Application,wwbbs_trwintags))
  635.                                                                         {
  636.                                                                             if(node_list=CreateList())
  637.                                                                                 {
  638.                                                                                     TR_SetAttribute(project,1,0,(ULONG) node_list);
  639.                                                                                     selected=0;
  640.                                                                                     TR_SetAttribute(project,1,TRAT_Value,selected);
  641.                                                                                     {
  642.                                                                                         struct MonitorNode *node;
  643.                                                                                         if(node=(struct MonitorNode *) GetNode(node_list,selected))
  644.                                                                                             UpdateStatus(project,node);
  645.                                                                                     }
  646.                                                                                 }
  647.                                                                             TR_SetAttribute(project,2,0,(ULONG) &action_list);
  648.                                                                         }
  649.                                                                     else
  650.                                                                         TR_EasyRequestTags(Application,TR_GetErrorString(TR_GetLastError(Application)),"Okay",TREZ_ReqPos,TRWP_CENTERDISPLAY,TREZ_Title,"World Wide BBS Error Request",TAG_END);
  651.                                                                     break;
  652.                                                             }
  653.                                                         break;
  654.                                                     case CXM_COMMAND:
  655.                                                         switch(id)
  656.                                                             {
  657.                                                                 case CXCMD_DISABLE:
  658.                                                                     ActivateCxObj(Broker,FALSE);
  659.                                                                     break;
  660.                                                                 case CXCMD_ENABLE:
  661.                                                                     ActivateCxObj(Broker,TRUE);
  662.                                                                     break;
  663.                                                                 case CXCMD_APPEAR:
  664.                                                                     if(project=TR_OpenProject(Application,wwbbs_trwintags))
  665.                                                                         {
  666.                                                                             if(node_list=CreateList())
  667.                                                                                 {
  668.                                                                                     TR_SetAttribute(project,1,0,(ULONG) node_list);
  669.                                                                                     selected=0;
  670.                                                                                     TR_SetAttribute(project,1,TRAT_Value,selected);
  671.                                                                                     {
  672.                                                                                         struct MonitorNode *node;
  673.                                                                                         if(node=(struct MonitorNode *) GetNode(node_list,selected))
  674.                                                                                             UpdateStatus(project,node);
  675.                                                                                     }
  676.                                                                                 }
  677.                                                                             TR_SetAttribute(project,2,0,(ULONG) &action_list);
  678.                                                                         }
  679.                                                                     else
  680.                                                                         TR_EasyRequestTags(Application,TR_GetErrorString(TR_GetLastError(Application)),"Okay",TREZ_ReqPos,TRWP_CENTERDISPLAY,TREZ_Title,"World Wide BBS Error Request",TAG_END);
  681.                                                                     break;
  682.                                                                 case CXCMD_DISAPPEAR:
  683.                                                                     break;
  684.                                                                 case CXCMD_KILL:
  685.                                                                     kg=FALSE;
  686.                                                                     break;
  687.                                                                 case CXCMD_UNIQUE:
  688.                                                                     if(project=TR_OpenProject(Application,wwbbs_trwintags))
  689.                                                                         {
  690.                                                                             if(node_list=CreateList())
  691.                                                                                 {
  692.                                                                                     TR_SetAttribute(project,1,0,(ULONG) node_list);
  693.                                                                                     selected=0;
  694.                                                                                     TR_SetAttribute(project,1,TRAT_Value,selected);
  695.                                                                                     {
  696.                                                                                         struct MonitorNode *node;
  697.                                                                                         if(node=(struct MonitorNode *) GetNode(node_list,selected))
  698.                                                                                             UpdateStatus(project,node);
  699.                                                                                     }
  700.                                                                                 }
  701.                                                                             TR_SetAttribute(project,2,0,(ULONG) &action_list);
  702.                                                                         }
  703.                                                                     else
  704.                                                                         TR_EasyRequestTags(Application,TR_GetErrorString(TR_GetLastError(Application)),"Okay",TREZ_ReqPos,TRWP_CENTERDISPLAY,TREZ_Title,"World Wide BBS Error Request",TAG_END);
  705.                                                                     break;
  706.                                                             }
  707.                                                         break;
  708.                                                 }
  709.                                         }
  710.                                 }
  711.                             if(mask & (1 << update_port->mp_SigBit))
  712.                                 {
  713.                                     struct UpdateMessage *msg;
  714.                                     while(msg=(struct UpdateMessage *) GetMsg(update_port))
  715.                                         {
  716.                                             switch(msg->um_Command)
  717.                                                 {
  718.                                                     case UPDCMD_UpdateStatus:
  719.                                                         break;
  720.                                                     case UPDCMD_StartupNode:
  721.                                                         {
  722.                                                             UBYTE type=0;
  723.                                                             BOOL frontend=FALSE;
  724.                                                             if(GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,msg->um_ID,NDTAG_Type,&type,NDTAG_FrontEnd,&frontend,TAG_END))
  725.                                                                 {
  726.                                                                     switch(type)
  727.                                                                         {
  728.                                                                             case NDTYP_Local:
  729.                                                                                 break;
  730.                                                                             case NDTYP_Remote:
  731.                                                                                 if(!frontend)
  732.                                                                                     StartProcess("WWBBS Node",NodeProc,20000,(BYTE *) msg->um_ID);
  733.                                                                                 else
  734.                                                                                     StartProcess("WWBBS Node",NodeFrontEndProc,20000,(BYTE *) msg->um_ID);
  735.                                                                                 break;
  736.                                                                         }
  737.                                                                 }
  738.                                                         }
  739.                                                         break;
  740.                                                     case UPDCMD_KillNode:
  741.                                                         {
  742.                                                             char task[64];
  743.                                                             BOOL istask=TRUE;
  744.                                                             sprintf(task,"WWBBS Local.%s",(BYTE *) msg->um_ID);
  745.                                                             while(istask)
  746.                                                                 {
  747.                                                                     Forbid();
  748.                                                                     istask=(FindTask(task)) ? TRUE : FALSE;
  749.                                                                     Permit();
  750.                                                                     if(istask)
  751.                                                                         {
  752.                                                                             while(!NodeCommandTags((BYTE *) msg->um_ID,NDCMD_Panic,TAG_END))
  753.                                                                                 Delay(25L);
  754.                                                                         }
  755.                                                                 }
  756.                                                         }
  757.                                                         KillProcess("WWBBS Node",(BYTE *) msg->um_ID);
  758.                                                         break;
  759.                                                 }
  760.                                             FreeVec(msg);
  761.                                         }
  762.                                 }
  763.                         }
  764.                 }
  765.             {
  766.                 struct Node *node;
  767.                 while(node=RemHead(&action_list))
  768.                     FreeVec(node);
  769.             }
  770.         }
  771.         if(node_list)
  772.             DeleteList(node_list);
  773.     }
  774.  
  775.     /* Kill nodes */
  776.     {
  777.         ULONG next=NULL;
  778.         BYTE *name=NULL;
  779.         UBYTE type=0;
  780.         while(next=GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,&name,CFGTAG_Next,next,NDTAG_Type,&type,TAG_END))
  781.             {
  782.                 switch(type)
  783.                     {
  784.                         case NDTYP_Local:
  785.                             NodeCommandTags(name,NDCMD_Panic,TAG_END);
  786.                             {
  787.                                 char task[64];
  788.                                 BOOL istask=TRUE;
  789.                                 sprintf(task,"WWBBS Local.%s",name);
  790.                                 while(istask)
  791.                                     {
  792.                                         Forbid();
  793.                                         istask=(FindTask(task)) ? TRUE : FALSE;
  794.                                         Permit();
  795.                                         if(istask)
  796.                                             Delay(25L);
  797.                                     }
  798.                             }
  799.                             break;
  800.                         case NDTYP_Remote:
  801.                             KillProcess("WWBBS Node",name);
  802.                             break;
  803.                     }
  804.             }
  805.     }
  806.  
  807.     /* Clean up update port */
  808.                 SetUpdatePort(NULL);
  809.                 DeleteMsgPort(update_port);
  810.             }
  811.     }
  812.  
  813.                                                         }
  814.                                                 }
  815.                                         }
  816.                                 }
  817.                             DeleteCxObjAll(Broker);
  818.                             {
  819.                                 struct Message *msg;
  820.                                 while(msg=GetMsg(BrokerMP))
  821.                                     ReplyMsg(msg);
  822.                             }
  823.                         }
  824.                     DeleteMsgPort(BrokerMP);
  825.                 }
  826.             ArgArrayDone();
  827.         }
  828.  
  829.                 close_all();
  830.             }
  831.         exit(0);
  832.     }
  833.  
  834. struct List *CreateList()
  835.     {
  836.         struct List *list=NULL;
  837.         if(list=AllocVec(sizeof(struct List),MEMF_CLEAR))
  838.             {
  839.                 NewList(list);
  840.                 {
  841.                     ULONG next=0;
  842.                     BYTE *name=NULL,username[33],location[33];
  843.                     struct MonitorNode *node;
  844.                     while(next=GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,&name,CFGTAG_Next,next,TAG_END))
  845.                         {
  846.                             if(node=AllocVec(sizeof(struct MonitorNode),MEMF_CLEAR))
  847.                                 {
  848.                                     if(GetStatusTags(STTAG_Name,name,STTAG_UserName,username,STTAG_Location,location,TAG_END))
  849.                                         sprintf(node->mn_Text,"%s: User `%s', Location `%s'",name,(strlen(username)) ? username : "None",(strlen(location)) ? location : "Nowhere");
  850.                                     else
  851.                                         sprintf(node->mn_Text,"%s: Idle",name);
  852.                                     strcpy(node->mn_Name,name);
  853.                                     node->mn_Node.ln_Name=node->mn_Text;
  854.                                     AddTail(list,(struct Node *) node);
  855.                                 }
  856.                         }
  857.                 }
  858.             }
  859.         return(list);
  860.     }
  861.  
  862. void DeleteList(struct List *list)
  863.     {
  864.         {
  865.             struct Node *node;
  866.             while(node=RemHead(list))
  867.                 FreeVec(node);
  868.         }
  869.         FreeVec(list);
  870.     }
  871.  
  872. struct Node *GetNode(struct List *list,ULONG num)
  873.     {
  874.         struct Node *node=NULL;
  875.         ULONG i;
  876.         if(list && list->lh_Head->ln_Succ)
  877.             {
  878.                 node=list->lh_Head;
  879.                 for(i=0;i<num;i++)
  880.                     {
  881.                         if(node->ln_Succ)
  882.                             node=node->ln_Succ;
  883.                     }
  884.             }
  885.         return(node);
  886.     }
  887.  
  888. ULONG GetNodeNum(struct List *list,BYTE *name)
  889.     {
  890.         ULONG ret=0;
  891.         if(list)
  892.             {
  893.                 struct MonitorNode *node=NULL;
  894.                 for(node=(struct MonitorNode *) list->lh_Head;node->mn_Node.ln_Succ;node=(struct MonitorNode *) node->mn_Node.ln_Succ)
  895.                     {
  896.                         if(!stricmp(node->mn_Name,name))
  897.                             break;
  898.                         ret++;
  899.                     }
  900.             }
  901.         return(ret);
  902.     }
  903.  
  904. void UpdateStatus(struct TR_Project *project,struct MonitorNode *node)
  905.     {
  906.         TR_SetAttribute(project,3,TRAT_Text,NULL);
  907.         TR_SetAttribute(project,4,TRAT_Text,NULL);
  908.         TR_SetAttribute(project,5,TRAT_Text,NULL);
  909.         TR_SetAttribute(project,6,TRAT_Text,NULL);
  910.         TR_SetAttribute(project,7,TRAT_Text,NULL);
  911.         TR_SetAttribute(project,8,TRAT_Text,NULL);
  912.         TR_SetAttribute(project,9,TRAT_Text,NULL);
  913.         TR_SetAttribute(project,10,TRAT_Text,NULL);
  914.         if(node)
  915.             {
  916.                 BYTE username[33];
  917.                 UWORD timeremaining=0,timeused=0;
  918.                 strcpy(username,"");
  919.                 if(GetStatusTags(STTAG_Name,node->mn_Name,STTAG_UserName,username,STTAG_TimeRemaining,&timeremaining,STTAG_TimeUsed,&timeused,TAG_END))
  920.                     {
  921.                         sprintf(time_buff,"%d used, %d remaining",timeused,timeremaining);
  922.                         TR_SetAttribute(project,6,TRAT_Text,(ULONG) time_buff);
  923.                         if(strlen(username))
  924.                             {
  925.                                 ULONG sessions=0;
  926.                                 UBYTE accesslevel=0,ratiobyte=0,ratiofile=0;
  927.                                 ULONG emailread=0,emailwritten=0,messagesread=0,messageswritten=0,filesuploaded=0,filesdownloaded=0,kilosuploaded=0,kilosdownloaded=0,creditsfile=0,creditskilo=0;
  928.                                 if(GetUserTags(USRTAG_Name,username,
  929.                                         USRTAG_Sessions,&sessions,
  930.                                         USRTAG_AccessLevel,&accesslevel,
  931.                                         USRTAG_RatioByte,&ratiobyte,
  932.                                         USRTAG_RatioFile,&ratiofile,
  933.                                         USRTAG_EmailRead,&emailread,
  934.                                         USRTAG_EmailWritten,&emailwritten,
  935.                                         USRTAG_MessagesRead,&messagesread,
  936.                                         USRTAG_MessagesWritten,&messageswritten,
  937.                                         USRTAG_FilesUploaded,&filesuploaded,
  938.                                         USRTAG_FilesDownloaded,&filesdownloaded,
  939.                                         USRTAG_KilosUploaded,&kilosuploaded,
  940.                                         USRTAG_KilosDownloaded,&kilosdownloaded,
  941.                                         USRTAG_FilesCredits,&creditsfile,
  942.                                         USRTAG_KilosCredits,&creditskilo,
  943.                                         TAG_END))
  944.                                     {
  945.                                         sprintf(sessions_buff,"%ld",sessions);
  946.                                         sprintf(access_buff,"%d",accesslevel);
  947.                                         strcpy(ratio_buff,"");
  948.                                         if(ratiobyte)
  949.                                             sprintf(&ratio_buff[strlen(ratio_buff)],"%d:1 byte",ratiobyte);
  950.                                         else
  951.                                             strcat(ratio_buff,"No byte ratio");
  952.                                         strcat(ratio_buff,", ");
  953.                                         if(ratiofile)
  954.                                             sprintf(&ratio_buff[strlen(ratio_buff)],"%d:1 file",ratiofile);
  955.                                         else
  956.                                             strcat(ratio_buff,"No file ratio");
  957.                                         sprintf(email_buff,"%ld read, %ld written",emailread,emailwritten);
  958.                                         sprintf(messages_buff,"%ld read, %ld written",messagesread,messageswritten);
  959.                                         sprintf(files_buff,"%ld (%ldK) uploaded, %ld (%ldK) downloaded",filesuploaded,kilosuploaded,filesdownloaded,kilosdownloaded);
  960.                                         sprintf(credits_buff,"%ld file, %ld kilo",creditsfile,creditskilo);
  961.                                         TR_SetAttribute(project,3,TRAT_Text,(ULONG) sessions_buff);
  962.                                         TR_SetAttribute(project,4,TRAT_Text,(ULONG) access_buff);
  963.                                         TR_SetAttribute(project,5,TRAT_Text,(ULONG) ratio_buff);
  964.                                         TR_SetAttribute(project,7,TRAT_Text,(ULONG) email_buff);
  965.                                         TR_SetAttribute(project,8,TRAT_Text,(ULONG) messages_buff);
  966.                                         TR_SetAttribute(project,9,TRAT_Text,(ULONG) files_buff);
  967.                                         TR_SetAttribute(project,10,TRAT_Text,(ULONG) credits_buff);
  968.                                     }
  969.                             }
  970.                     }
  971.             }
  972.     }
  973.  
  974. void close_all()
  975.     {
  976.         if(WorldWideBase) CloseLibrary(WorldWideBase);
  977.         TR_CloseTriton();
  978.         exit(0);
  979.     }
  980.  
  981. /***/
  982.  
  983. BOOL __saveds StartProcess(BYTE *basename,APTR entry,ULONG stacksize,BYTE *id)
  984.     {
  985.         static BYTE name[64];
  986.         struct MsgPort *replyport;
  987.         struct Process *proc;
  988.         BOOL ret=FALSE;
  989.         sprintf(name,"%s.%s",basename,id);
  990.         if(replyport=CreateMsgPort())
  991.             {
  992.                 struct ConfirmationMessage msg={0};
  993.                 msg.cm_Message.mn_Node.ln_Type=NT_MESSAGE;
  994.                 msg.cm_Message.mn_Length=sizeof(struct ConfirmationMessage);
  995.                 msg.cm_Message.mn_ReplyPort=replyport;
  996.                 msg.cm_ID=id;
  997.                 if(proc=CreateNewProcTags(NP_Entry,entry,NP_StackSize,stacksize,NP_Name,name,TAG_END))
  998.                     {
  999.                         PutMsg(&proc->pr_MsgPort,(struct Message *) &msg);
  1000.                         WaitPort(replyport);
  1001.                         GetMsg(replyport);
  1002.                         ret=msg.cm_Return;
  1003.                     }
  1004.                 DeleteMsgPort(replyport);
  1005.             }
  1006.         return(ret);
  1007.     }
  1008.  
  1009. void __saveds KillProcess(BYTE *basename,BYTE *id)
  1010.     {
  1011.         struct MsgPort *port=NULL;
  1012.         BYTE name[64];
  1013.         sprintf(name,"%s.%s",basename,id);
  1014.         Forbid();
  1015.         port=FindPort(name);
  1016.         Permit();
  1017.         if(port)
  1018.             {
  1019.                 if(!strcmp(basename,"WWBBS Node"))
  1020.                     {
  1021.                         while(!NodeCommandTags(id,NDCMD_Quit,TAG_END))
  1022.                             Delay(25L);
  1023.                     }
  1024.                 if(!strcmp(basename,"WWBBS Console"))
  1025.                     {
  1026.                         while(!ConsoleCommandTags(id,CONCMD_Quit,TAG_END))
  1027.                             Delay(25L);
  1028.                     }
  1029.                 if(!strcmp(basename,"WWBBS Serial"))
  1030.                     {
  1031.                         while(!SerialCommandTags(id,SERCMD_Quit,TAG_END))
  1032.                             Delay(25L);
  1033.                     }
  1034.                 if(!strcmp(basename,"WWBBS Timer"))
  1035.                     {
  1036.                         while(!TimerCommandTags(id,TMRCMD_Quit,TAG_END))
  1037.                             Delay(25L);
  1038.                     }
  1039.             }
  1040.     }
  1041.